package main

import (
	"fmt"
	"strconv"
)

type MyStu struct {
	Name string
	Age  int
}

// 因为接收者是val类型，所以调用时本质是使用一个MyStu的副本，对于其的更改不会对外部生效
func (s MyStu) AgeAddOne() {
	s.Age++
}

// 如果接收者是指针类型，方法内部的更改会对于外部生效
func (s *MyStu) AgeAddOnePtr() {
	s.Age++
}

func (s MyStu) getInfoValReceiver() string {
	return s.Name + "..." + strconv.Itoa(s.Age)
}

func (s *MyStu) getInfoPtrReceiver() string {
	return s.Name + "..." + strconv.Itoa(s.Age)
}

func main() {
	demo1StuAdd()
	demo2StuInfo()
}

func demo1StuAdd() {
	stu := MyStu{Name: "sdclone", Age: 5}
	stu.AgeAddOne()    // 修改不生效
	fmt.Println(stu)   // {sdclone 5}
	stu.AgeAddOnePtr() // 修改生效
	fmt.Println(stu)   // {sdclone 6}

	stu2 := &MyStu{Name: "sdclone", Age: 19}
	stu2.AgeAddOne()    // 修改不生效
	fmt.Println(stu2)   // &{sdclone 19}
	stu2.AgeAddOnePtr() // 修改生效
	fmt.Println(stu2)   // &{sdclone 20}
}

func demo2StuInfo() {
	stu := MyStu{Name: "sdclone", Age: 5}
	fmt.Println(stu.getInfoValReceiver()) // sdclone...5
	fmt.Println(stu.getInfoPtrReceiver()) // sdclone...5

	stuPtr := &MyStu{Name: "sdclone", Age: 5}
	fmt.Println(stuPtr.getInfoValReceiver()) // sdclone...5
	fmt.Println(stuPtr.getInfoPtrReceiver()) // sdclone...5

}
